﻿using System;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEditor;

namespace Nirvana
{

    [Serializable]
    public class FontAtlas
    {
        [SerializeField]
        public string fontName;

        [SerializeField]
        public FontItem[] glyphs;
    }

    [Serializable]
    public class FontItem
    {
        [SerializeField]
        public int code;
        [SerializeField]
        public Texture2D image;
    }

    /// <summary>
    /// 数字字体图集创建脚本
    /// </summary>
    [CreateAssetMenu(fileName = "FontMaker", menuName = "Nirvana/UI/FontMaker")]
    public class FontMaker : ScriptableObject
    {

        [SerializeField]
        private string atlasName;

        [SerializeField]
        private int padding;

        [SerializeField]
        private int maximumAtlasSize = 2048;
        [SerializeField]
        private FontAtlas[] fonts;

        public void Build()
        {
            using (ProgressIndicator progressIndicator = new ProgressIndicator("Make Font"))
            {
                this.Build(progressIndicator);
            }
        }

        private void Build(ProgressIndicator progressIndicator)
        {
            progressIndicator.Show("Process font images...");
            List<Texture2D> list = new List<Texture2D>();
            foreach (FontAtlas f in this.fonts)
            {
                foreach (FontItem p in f.glyphs)
                {
                    if (p.image == null)
                    {
                        Debug.LogErrorFormat("The font {0} with graph: {1} is missing texture.", new object[]
                        {
                            f.fontName,
                            p.code
                        });
                    }
                    else
                    {
                        string assetPath = AssetDatabase.GetAssetPath(p.image);
                        TextureImporter textureImporter = AssetImporter.GetAtPath(assetPath) as TextureImporter;
                        if (textureImporter != null)
                        {
                            if (textureImporter.textureType != TextureImporterType.Sprite)
                                textureImporter.textureType = TextureImporterType.Sprite;

                            bool flag = false;
                            if (!textureImporter.isReadable)
                            {
                                textureImporter.isReadable = true;
                                flag = true;
                            }
                            if (textureImporter.textureCompression != TextureImporterCompression.Uncompressed)
                            {
                                textureImporter.textureCompression = TextureImporterCompression.Uncompressed;
                                flag = true;
                            }

                            if (textureImporter.mipmapEnabled)
                            {
                                textureImporter.mipmapEnabled = false;
                                flag = true;
                            }
                            if (textureImporter.npotScale != TextureImporterNPOTScale.None)
                            {
                                textureImporter.npotScale = TextureImporterNPOTScale.None;
                                flag = true;
                            }
                            //sprite必须RBGA32
                            var defaultformat = textureImporter.GetDefaultPlatformTextureSettings();
                            if (defaultformat.format != TextureImporterFormat.RGBA32)
                            {
                                defaultformat.format = TextureImporterFormat.RGBA32;
                                textureImporter.SetPlatformTextureSettings(defaultformat);
                                flag = true;
                            }

                            if (flag)
                            {
                                textureImporter.SaveAndReimport();
                            }
                        }
                        list.Add(p.image);
                    }
                }
            }

            progressIndicator.SetProgress(0.25f);
            progressIndicator.Show("Build font atlas...");
            Texture2D fontatlas = new Texture2D(0, 0, TextureFormat.ARGB32, false);
            fontatlas.name = "Font Atlas";
            Rect[] packtextures = fontatlas.PackTextures(list.ToArray(), this.padding, this.maximumAtlasSize, false);
            string assetPath2 = AssetDatabase.GetAssetPath(this);
            string directoryName = Path.GetDirectoryName(assetPath2);
            string text = this.atlasName;
            if (!text.EndsWith(".png") || !text.EndsWith(".PNG"))
            {
                text += ".png";
            }
            string text2 = Path.Combine(directoryName, text);
            byte[] array4 = ImageConversion.EncodeToPNG(fontatlas);
            FileStream fileStream = File.OpenWrite(text2);
            fileStream.Write(array4, 0, array4.Length);
            fileStream.Close();
            AssetDatabase.Refresh();

            TextureImporter textureImporter2 = AssetImporter.GetAtPath(text2) as TextureImporter;
            if (textureImporter2 != null)
            {
                bool flag2 = false;
                if (textureImporter2.isReadable)
                {
                    textureImporter2.isReadable = false;
                    flag2 = true;
                }
                if (!textureImporter2.alphaIsTransparency)
                {
                    textureImporter2.alphaIsTransparency = true;
                    flag2 = true;
                }
                if (flag2)
                {
                    textureImporter2.SaveAndReimport();
                }
            }

            Texture mainTexture = AssetDatabase.LoadAssetAtPath<Texture>(text2);
            progressIndicator.SetProgress(0.35f);
            progressIndicator.Show("Build font material...");
            string path = this.atlasName + ".mat";
            string text3 = Path.Combine(directoryName, path);
            Material material = AssetDatabase.LoadAssetAtPath<Material>(text3);
            if (material == null)
            {
                Shader shader = Shader.Find("Transparent/Diffuse");
                material = new Material(shader);
                AssetDatabase.CreateAsset(material, text3);
            }
            material.mainTexture = mainTexture;
            EditorUtility.SetDirty(material);
            AssetDatabase.SaveAssets();
            progressIndicator.SetProgress(0.7f);
            progressIndicator.Show("Build font settings...");
            int num = 0;
            foreach (FontAtlas f in this.fonts)
            {
                FontItem[] fontitems = f.glyphs;
                if (fontitems.Length != 0)
                {
                    string fontname = f.fontName;
                    if (!fontname.EndsWith(".fontsettings"))
                    {
                        fontname += ".fontsettings";
                    }
                    string fontpath = Path.Combine(directoryName, fontname);
                    Font font = AssetDatabase.LoadAssetAtPath<Font>(fontpath);
                    if (font == null)
                    {
                        font = new Font();
                        AssetDatabase.CreateAsset(font, fontpath);
                    }
                    float num2 = 0f;
                    CharacterInfo[] charInfos = new CharacterInfo[fontitems.Length];
                    for (int l = 0; l < fontitems.Length; l++)
                    {
                        FontItem t = fontitems[l];
                        Texture2D image = t.image;
                        Rect rect = packtextures[num++];
                        if (num2 < (float)image.height)
                        {
                            num2 = (float)image.height;
                        }
                        CharacterInfo characterInfo = default(CharacterInfo);
                        characterInfo.index = t.code;
                        float x = rect.x;
                        float y = rect.y;
                        float width = rect.width;
                        float height = rect.height;
                        characterInfo.uvBottomLeft = new Vector2(x, y);
                        characterInfo.uvBottomRight = new Vector2(x + width, y);
                        characterInfo.uvTopLeft = new Vector2(x, y + height);
                        characterInfo.uvTopRight = new Vector2(x + width, y + height);
                        characterInfo.minX = 0;
                        characterInfo.minY = -image.height;
                        characterInfo.maxX = image.width;
                        characterInfo.maxY = 0;
                        characterInfo.advance = image.width;
                        charInfos[l] = characterInfo;
                    }
                    font.characterInfo = charInfos;
                    font.material = material;
                    SerializedObject serializedObject = new SerializedObject(font);
                    serializedObject.Update();
                    SerializedProperty serializedProperty = serializedObject.FindProperty("m_LineSpacing");
                    serializedProperty.floatValue = num2;
                    serializedObject.ApplyModifiedPropertiesWithoutUndo();
                    EditorUtility.SetDirty(font);

                }
            }
            progressIndicator.SetProgress(0.95f);
            progressIndicator.Show("Save and refresh assets.");
            AssetDatabase.SaveAssets();
            AssetDatabase.Refresh();
        }
    }
}

